iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 28
1
Mobile Development

Flutter 程式設計入門實戰 30 天系列 第 28

Day 28:Sqflite 資料庫存取

  • 分享至 

  • xImage
  •  

2024 最新 Flutter 教學 - Flutter 終極指南: 連結
從零開始學 Dart 程式設計: 連結
Flutter 程式設計入門實戰 30 天: 連結


哈囉~大家好,我是 KT ,今天【iT邦幫忙鐵人賽】挑戰第二十八天,KT 將為大家來介紹,Sqflite 資料庫存取。

Sqflite 資料庫存取

當你需要大量資料存在手機端,可以採用 SQLite 資料庫,而 Flutter 會透過 sqflite 這個套件來處理 SQLite 資料庫。

新增加入 sqflite 和 path 套件

最新版號,可以連結至 pub.dev 進行查詢:

dependencies:
  flutter:
    sdk: flutter
  sqflite: ^1.1.6
  path: ^1.6.2

PS. ^表示與當前大版號一致的版本,〜表示和當前小版號一致的版本。

加入位置實際範例

定義數據模型

定義一個狗狗的數據模型,裡面共有三個資料欄位,分別是:

  • id:識別欄位,唯一值為整數資料類型
  • name:存放狗狗名字為字串資料類型
  • age:存放狗狗年齡,為整數資料類型。
class Dog {
  final int id;
  final String name;
  final int age;

  Dog({this.id, this.name, this.age});
}

開啟資料庫

openDatabase 開啟資料庫,搭配 path 套件的 join 方法來確保多平台運行正常。不會因平台差異導致開啟位置錯誤。

 final database = openDatabase(
    join(await getDatabasesPath(), 'doggie_database.db'),);

Create,建立資料表

SQLite 常用資料類型介紹

資料名稱 資料類型
TEXT 文字資料
INTEGER 整數資料
final Future<Database> database = openDatabase(

  join(await getDatabasesPath(), 'doggie_database.db'),
  onCreate: (db, version) {
    // 執行 CREATE TABLE 的 SQLite 語法,來建立資料表。
    // 設定 id 為整數 PRIMARY KEY 主鍵值
    return db.execute(
      "CREATE TABLE dogs(id INTEGER PRIMARY KEY, name TEXT, age INTEGER)",
    );
  },
  //設定版本號碼,提供資料庫升版或降版使用
  version: 1,
);

insert,插入一筆資料

數據模型,加入轉 Map 方法

將狗狗的數據模型,加入轉 Map 方法,方便等一下執行插入語法

class Dog {
  final int id;
  final String name;
  final int age;

  Dog({this.id, this.name, this.age});

  Map<String, dynamic> toMap() {
    return {
      'id': id,
      'name': name,
      'age': age,
    };
  }
}

定義插入方法

Future<void> insertDog(Dog dog) async {
  //引用資料庫
  final Database db = await database;

  // 插入狗狗資料庫語法
  await db.insert(
    'dogs',
    dog.toMap(),
    //當資料發生衝突,定義將會採用 replace 覆蓋之前的資料 
    conflictAlgorithm: ConflictAlgorithm.replace,
  );
}

建立一筆狗狗數據資料

final fido = Dog(
  id: 0, 
  name: 'Fido', 
  age: 35,
);

執行插入語法

await insertDog(fido);

Query,查詢資料

自定義一個查詢方法

Future<List<Dog>> dogs() async {
    //引用資料庫
    final Database db = await database;

    // 查詢狗狗資料庫語法
    final List<Map<String, dynamic>> maps = await db.query('dogs');

//將 List<Map<String, dynamic> 轉換成 List<Dog> 資料類型
    return List.generate(maps.length, (i) {
      return Dog(
        id: maps[i]['id'],
        name: maps[i]['name'],
        age: maps[i]['age'],
      );
    });
  }

執行查詢語法,獲取資料後印出

print(await dogs());

Update,更新資料

Future<void> updateDog(Dog dog) async {
    //引用資料庫
    final db = await database;

    // 查詢狗狗資料庫語法
    await db.update(
      'dogs',
      dog.toMap(),
     //確定給定的狗狗id是否匹配
      where: "id = ?",
     //通過 whereArg 傳遞狗狗的 id 可以防止 SQL 注入
     //注意 不要使用 where: "id = ${dog.id}"
      whereArgs: [dog.id],
    );
  }

更新數據

//更新年齡資料
 fido = Dog(
    id: fido.id,
    name: fido.name,
    age: fido.age + 7,
  );

//執行更新語法
await updateDog(fido);

//印出更新後的資料
print(await dogs());

Delete,刪除資料

Future<void> deleteDog(int id) async {
    //引用資料庫
  final db = await database;

  //刪除語法
  await db.delete(
    'dogs',
    where: "id = ?",
    whereArgs: [id],
  );
}

刪除數據

//執行刪除語法
await deleteDog(fido.id);
//印出刪除後的資料
print(await dogs());

完整程式碼

import 'dart:async';

import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';

void main() async {
  final database = openDatabase(
    join(await getDatabasesPath(), 'doggie_database.db'),

    onCreate: (db, version) {
      return db.execute(
        "CREATE TABLE dogs(id INTEGER PRIMARY KEY, name TEXT, age INTEGER)",
      );
    },
  
    version: 1,
  );

  Future<void> insertDog(Dog dog) async {

    final Database db = await database;

    await db.insert(
      'dogs',
      dog.toMap(),
      conflictAlgorithm: ConflictAlgorithm.replace,
    );
  }

  Future<List<Dog>> dogs() async {

    final Database db = await database;


    final List<Map<String, dynamic>> maps = await db.query('dogs');

    return List.generate(maps.length, (i) {
      return Dog(
        id: maps[i]['id'],
        name: maps[i]['name'],
        age: maps[i]['age'],
      );
    });
  }

  Future<void> updateDog(Dog dog) async {

    final db = await database;

    await db.update(
      'dogs',
      dog.toMap(),

      where: "id = ?",

      whereArgs: [dog.id],
    );
  }

  Future<void> deleteDog(int id) async {

    final db = await database;


    await db.delete(
      'dogs',
      where: "id = ?",
      whereArgs: [id],
    );
  }

  var fido = Dog(
    id: 0,
    name: 'Fido',
    age: 35,
  );

  await insertDog(fido);

  print(await dogs());

  fido = Dog(
    id: fido.id,
    name: fido.name,
    age: fido.age + 7,
  );
  await updateDog(fido);

  print(await dogs());

  await deleteDog(fido.id);

  print(await dogs());
}

class Dog {
  final int id;
  final String name;
  final int age;

  Dog({this.id, this.name, this.age});

  Map<String, dynamic> toMap() {
    return {
      'id': id,
      'name': name,
      'age': age,
    };
  }

  @override
  String toString() {
    return 'Dog{id: $id, name: $name, age: $age}';
  }
}

執行畫面


那今天【iT邦幫忙鐵人賽】就介紹到這邊囉~

順帶一提,KT 線上教室,臉書粉絲團,會不定期發佈相關資訊,不想錯過最新資訊,不要忘記來按讚,加追蹤喔!也歡迎大家將這篇文章分享給更多人喔。

我們明天見囉!!!掰掰~

參考資料

HKT 線上教室
http://tw-hkt.blogspot.com/

Background vector created by freepik
https://www.freepik.com

Persist data with SQLite
https://flutter.dev/docs/cookbook/persistence/sqlite


上一篇
Day 27:SharedPreferences 資料存取
下一篇
Day 29:Provider 狀態管理
系列文
Flutter 程式設計入門實戰 30 天30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言